#include "OperationAudio.h"

extern u8 gamewav[];
	  
OperationAudio::OperationAudio()
{
   samplerate  = 0;
   gamesamples = 0;
   SOUNDENABLED = false;
}

OperationAudio::~OperationAudio()
{

}

/****************************************************************************
* FLIP16 - Switch from LE to BE
****************************************************************************/
u16
OperationAudio::FLIP16 (u16 value)
{
  return ((value & 0xff) << 8) | ((value & 0xff00) >> 8);
}

/****************************************************************************
* FLIP32 - Switch from LE to BE
****************************************************************************/
u32
OperationAudio::FLIP32 (u32 value)
{
  u32 b;

  b = (value & 0xff) << 24;
  b |= (value & 0xff00) << 8;
  b |= (value & 0xff0000) >> 8;
  b |= (value & 0xff000000) >> 24;

  return b;
}

/****************************************************************************
* CvtWave
*
* Convert PC (x86) WAVE to GC Raw Audio
****************************************************************************/
u32
OperationAudio::CvtWave (u8 *wavebuffer)
{
  WAVEHDR wavhdr;
  WAVEDATAHDR datahdr;
  int samples;
  int i;
  u16 *src, *dst;

	/*** Capture the WAV file header ***/
  memcpy (&wavhdr, wavebuffer, sizeof (WAVEHDR));

	/*** Do some basic checking ***/
  if (memcmp (&wavhdr.RIFF, "RIFF", 4))
    return 0;

  if (memcmp (&wavhdr.WAVE, "WAVE", 4))
    return 0;

  if (memcmp (&wavhdr.waFmt, "fmt ", 4))
    return 0;

	/*** Important!
	 * Wave file must be type 1 == Uncompressed PCM
	 */
  if (FLIP16 (wavhdr.fmtType) != 1)
    return 0;

	/*** Looking good! - So capture the sample rate ***/
  samplerate = FLIP32 (wavhdr.fmtRate);
  if ((samplerate != 32000) && (samplerate != 48000))
    return 0;

	/*** Also need 2 channels ***/
  if (FLIP16 (wavhdr.fmtChannels) != 2)
    return 0;

	/*** Pickup the data header ***/
  memcpy (&datahdr, wavebuffer + 20 + FLIP32 (wavhdr.fmtSize), 8);

  if (memcmp (&datahdr.WAVEDATA, "data", 4))
    return 0;

  samples = FLIP32 (datahdr.waSize);
  samples >>= 1;

	/***
	 * NB: Sound data MUST be aligned to 32 bytes.
	 */
  src = (u16 *) wavebuffer + 28 + FLIP32 (wavhdr.fmtSize);
  dst = (u16 *) wavebuffer;

  for (i = 0; i < samples; i++)
    dst[i] = FLIP16 (src[i]);

  return samples << 1;
}

   
   
void OperationAudio::InitAudio()
{
	AUDIO_Init(NULL);
	SOUNDENABLED = true;
}
   
void OperationAudio::PlayGameMusic()
{
	if(SOUNDENABLED)
	{
	  if(!gamesamples)
	  {
	     gamesamples = CvtWave (gamewav);

	     if (gamesamples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (gamewav, gamesamples);
	     }
	  }

	  if(gamesamples)
 	  {
	     AUDIO_InitDMA ((u32) gamewav, gamesamples);
	     AUDIO_StartDMA ();
	   }	
	}

}
   
void OperationAudio::StopGameMusic()
{	      
    if(SOUNDENABLED)
		AUDIO_StopDMA ();

}
